package com.atxiao;

import com.jcraft.jsch.*;

import java.io.*;
import java.util.*;

public class SeverUtil {


    /**
     * sftp工具类
     *
     */
    private ChannelSftp sftp = null;
    private Session sshSession = null;

    /**
     * 通过SFTP连接服务器
     */
    public void connect(String ip,String port,String userName,String password){
        try{
            System.out.println("sft链接开始---》connect---begin");
            int sftpPort = 22;//端口号
            if(null != port && !"".equals(port)){
                sftpPort = Integer.valueOf(port);
            }
            JSch jsch = new JSch();
            jsch.getSession(userName, ip, sftpPort);
            sshSession = jsch.getSession(userName, ip, sftpPort);
            System.out.println("ip="+ip+"--->port"+port);
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            // 登录
            sshSession.setTimeout(10000);
            sshSession.connect();
            System.out.println("sftp链接成功------>success");
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            String home = sftp.getHome();
            Vector<File> vector = sftp.ls("/home/demo");
            for (File file : vector) {
                System.out.println(file);
            }
            sftp.cd("/home/demo/");

            OutputStream outputStream = sftp.getOutputStream();

            System.out.println(home);
//===================================================================================================
//            String filePath="/home/demo/demo.txt";
//            File file = new File(filePath);
//            if (!file .getParentFile().exists()) {
//                file .getParentFile().mkdirs();
//            }
//            if(!file .exists()) {
//                file .createNewFile();
//            }
//
//            file.setExecutable(true);
//            file.setReadable(true);
//            file.setWritable(true);
//
//
//            OutputStream os = new FileOutputStream(file);
//            os.write("DemoString".getBytes("GBK"));



//            FileInputStream fis = new FileInputStream(new File("/home/demo"));
//            System.out.println(fis);

            System.out.println("sft链接结束---》connect---end");
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     */
    public void disconnect() {
        System.out.println("sft关闭链接开始---》disconnect---begin");
        if (this.sftp != null) {
            if (this.sftp.isConnected()) {
                this.sftp.disconnect();
            }
        }
        if (this.sshSession != null) {
            if (this.sshSession.isConnected()) {
                this.sshSession.disconnect();
            }
        }
        System.out.println("sft关闭链接结束---》disconnect---end");
    }

    /**
     * 批量下载文件
     *
     * @param remotePath：远程下载目录(以路径符号结束,可以为相对路径eg:/assess/sftp/jiesuan_2/2014/)
     * @param localPath：本地保存目录(以路径符号结束,D:\Duansha\sftp\)
     * @param fileFormat：下载文件格式(以特定字符开头,为空不做检验)
     * @param fileEndFormat：下载文件格式(文件格式)
     * @param del：下载后是否删除sftp文件
     * @return
     */
    public List<String> batchDownLoadFile(String remotePath, String localPath,
                                          String fileFormat, String fileEndFormat, boolean del) {
        List<String> filenames = new ArrayList<String>();
        try {
            // connect();
            Vector v = listFiles(remotePath);
            // sftp.cd(remotePath);
            if (v.size() > 0) {
                System.out.println("本次处理文件个数不为零,开始下载...fileSize=" + v.size());
                Iterator it = v.iterator();
                while (it.hasNext()) {
                    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) it.next();
                    String filename = entry.getFilename();
                    SftpATTRS attrs = entry.getAttrs();
                    if (!attrs.isDir()) {
                        boolean flag = false;
                        String localFileName = localPath + filename;
                        fileFormat = fileFormat == null ? "" : fileFormat
                                .trim();
                        fileEndFormat = fileEndFormat == null ? ""
                                : fileEndFormat.trim();
                        // 三种情况
                        if (fileFormat.length() > 0 && fileEndFormat.length() > 0) {
                            if (filename.startsWith(fileFormat) && filename.endsWith(fileEndFormat)) {
                                flag = downloadFile(remotePath, filename, localPath, filename);
                                if (flag) {
                                    filenames.add(localFileName);
                                    if (flag && del) {
                                        deleteSFTP(remotePath, filename);
                                    }
                                }
                            }
                        } else if (fileFormat.length() > 0 && "".equals(fileEndFormat)) {
                            if (filename.startsWith(fileFormat)) {
                                flag = downloadFile(remotePath, filename, localPath, filename);
                                if (flag) {
                                    filenames.add(localFileName);
                                    if (flag && del) {
                                        deleteSFTP(remotePath, filename);
                                    }
                                }
                            }
                        } else if (fileEndFormat.length() > 0 && "".equals(fileFormat)) {
                            if (filename.endsWith(fileEndFormat)) {
                                flag = downloadFile(remotePath, filename, localPath, filename);
                                if (flag) {
                                    filenames.add(localFileName);
                                    if (flag && del) {
                                        deleteSFTP(remotePath, filename);
                                    }
                                }
                            }
                        } else {
                            flag = downloadFile(remotePath, filename, localPath, filename);
                            if (flag) {
                                filenames.add(localFileName);
                                if (flag && del) {
                                    deleteSFTP(remotePath, filename);
                                }
                            }
                        }
                    }
                }
            }
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            // this.disconnect();
        }
        return filenames;
    }

    /**
     * 下载单个文件
     *
     * @param ftpPath：远程下载目录(以路径符号结束)
     * @param remoteFileName：下载文件名
     * @param localPath：本地保存目录(以路径符号结束)
     * @param localFileName：保存文件名
     * @return
     */
    public boolean downloadFile(String ftpPath, String remoteFileName, String localPath, String localFileName) {
        FileOutputStream fieloutput = null;
        System.out.println("sftp下载文件开始----->downLoad---begin");
        try {
            System.out.println("本地文件路径名称"+localPath + localFileName);
            File file1 = new File(localPath);
            if(!file1.exists()){
                file1.mkdirs();
            }
            File file = new File(localPath + localFileName);
            fieloutput = new FileOutputStream(file);
            System.out.println("服务器文件路径名称"+ftpPath + remoteFileName);
            sftp.get(ftpPath + remoteFileName, fieloutput);
            System.out.println("sftp下载文件结束----->downLoad---end");
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            if (null != fieloutput) {
                try {
                    fieloutput.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 上传单个文件
     *
     * @param remotePath：远程保存目录
     * @param remoteFileName：保存文件名
     * @param localPath：本地上传目录(以路径符号结束)
     * @param localFileName：上传的文件名
     * @return
     */
    public boolean uploadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
        FileInputStream in = null;
        try {
            createDir(remotePath);
            File file = new File(localPath + localFileName);
            in = new FileInputStream(file);
            sftp.put(in, remoteFileName);
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (SftpException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 批量上传文件
     *
     * @param remotePath：远程保存目录
     * @param localPath：本地上传目录(以路径符号结束)
     * @param del：上传后是否删除本地文件
     * @return
     */
    public boolean bacthUploadFile(String remotePath, String localPath, boolean del) {
        try {
            File file = new File(localPath);
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile()
                        && files[i].getName().indexOf("bak") == -1) {
                    if (this.uploadFile(remotePath, files[i].getName(),
                            localPath, files[i].getName())	&& del) {
                        deleteFile(localPath + files[i].getName());
                    }
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            this.disconnect();
        }
        return false;

    }

    /**
     * 删除本地文件
     *
     * @param filePath
     * @return
     */
    public boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return false;
        }

        if (!file.isFile()) {
            return false;
        }
        boolean rs = file.delete();
        return rs;
    }

    /**
     * 创建目录
     *
     * @param createpath
     * @return
     */
    public boolean createDir(String createpath) {
        try {
            if (isDirExist(createpath)) {
                this.sftp.cd(createpath);
                return true;
            }
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString())) {
                    sftp.cd(filePath.toString());
                } else {
                    // 建立目录
                    sftp.mkdir(filePath.toString());
                    // 进入并设置为当前目录
                    sftp.cd(filePath.toString());
                }

            }
            this.sftp.cd(createpath);
            return true;
        } catch (SftpException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 判断目录是否存在
     *
     * @param directory
     * @return
     */
    public boolean isDirExist(String directory) {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }

    /**
     * 删除stfp文件
     *
     * @param directory：要删除文件所在目录
     * @param deleteFile：要删除的文件
     */
    public void deleteSFTP(String directory, String deleteFile) {
        try {
            // sftp.cd(directory);
            sftp.rm(directory + deleteFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 如果目录不存在就创建目录
     *
     * @param path
     */
    public void mkdirs(String path) {
        File f = new File(path);

        String fs = f.getParent();

        f = new File(fs);

        if (!f.exists()) {
            f.mkdirs();
        }
    }

    /**
     * 列出目录下的文件
     *
     * @param directory：要列出的目录
     * @return
     * @throws SftpException
     */
    public Vector listFiles(String directory) throws SftpException {
        return sftp.ls(directory);
    }


    /**
     * 测试
     */
    public static void main(String[] args) throws Exception {
         ChannelSftp sftp = null;
         Session sshSession = null;



//        System.out.println(new File(".").getAbsolutePath());

//        String path="http:\\182.92.57.72";

//        File file1 = new File("/home/demo");
//        file1.setWritable(true,false);
//        FileOutputStream fos = new FileOutputStream(file1);
//        fos.write("ddd".getBytes());


//        FileInputStream fis = new FileInputStream(new File(path+"\\home\\demo"));
//        System.out.println(fis);

        // 本地存放地址

        // Sftp下载路径
        String sftpPath = "/home/demo/test.txt";

        String port="22";
        String ip="182.92.57.72";
        String userName="root";
        String password="Lx0000....";


        SeverUtil util = new SeverUtil();
        try {

            util.connect(ip,port,userName,password);
//             //上传
//            String remotePath="/home/demo";
//            String remoteFileName="test.txt";
//            String localPath = "E:/";
//            String localFileName="demo.txt";
//            boolean flag = util.uploadFile(remotePath, remoteFileName, localPath, localFileName);
//            System.out.println(flag);

            File file = new File(sftpPath);
            FileInputStream ins = new FileInputStream(file);
//            int read = fis.read("NIHAOI".getBytes());
//            System.out.println(read);


//

            String ftpPath="/home/demo/";
            String remoteFileName="test.txt";
            String localPath="E:/20210820";
            String localFileName="demo.txt";
            boolean falg = util.downloadFile(ftpPath, remoteFileName, localPath, localFileName);
            System.out.println(falg);


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            util.disconnect();
        }
    }




}
